package com.easylinkin.linkappapi.keywork.utils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

public class ExcelExportUtils {

    /**
     * 导出Excel到浏览器（带合并标题行）
     * @param response HttpServletResponse对象
     * @param fileName 导出文件名（不带后缀）
     * @param sheetName 工作表名称
     * @param title 标题内容（合并首行显示）
     * @param headers 表头数组
     * @param data 数据列表
     * @throws IOException
     */
    public static void exportWithTitle(HttpServletResponse response, String fileName,
                                       String sheetName, String title,
                                       String[] headers, List<Map<String, Object>> data) throws IOException {
        // 1. 设置响应头
        setResponseHeader(response, fileName);

        // 2. 创建工作簿
        try (Workbook workbook = new XSSFWorkbook();
             OutputStream out = response.getOutputStream()) {

            // 3. 创建工作表
            Sheet sheet = workbook.createSheet(sheetName);

            // 4. 设置默认列宽
            sheet.setDefaultColumnWidth(18);

            // 5. 创建样式
            CellStyle titleStyle = createTitleCellStyle(workbook);
            CellStyle headerStyle = createHeaderCellStyle(workbook);
            CellStyle dataStyle = createDataCellStyle(workbook);

            // 6. 创建标题行（合并单元格）
            createTitleRow(sheet, title, headers.length, titleStyle);

            // 7. 创建表头行
            createHeaderRow(sheet, headers, headerStyle);

            // 8. 填充数据行
            fillDataRows(sheet, headers, data, dataStyle);

            // 9. 自动调整列宽
            autoSizeColumns(sheet, headers.length);

            // 10. 写入输出流
            workbook.write(out);
            out.flush();
        }
    }

    /**
     * 设置响应头（处理中文文件名）
     */
    private static void setResponseHeader(HttpServletResponse response, String fileName) throws IOException {
        String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment;filename*=UTF-8''" + encodedFileName + ".xlsx");
        response.setCharacterEncoding("UTF-8");
    }

    /**
     * 创建标题行样式（合并单元格）
     */
    private static CellStyle createTitleCellStyle(Workbook workbook) {
        CellStyle style = workbook.createCellStyle();
        // 设置背景色
        style.setFillForegroundColor(IndexedColors.GREY_80_PERCENT.getIndex());
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        // 设置边框
        style.setBorderBottom(BorderStyle.MEDIUM);
        style.setBorderTop(BorderStyle.MEDIUM);
        style.setBorderRight(BorderStyle.MEDIUM);
        style.setBorderLeft(BorderStyle.MEDIUM);
        // 设置字体
        Font font = workbook.createFont();
        font.setBold(true);
        font.setFontHeightInPoints((short) 16);
        font.setColor(IndexedColors.WHITE.getIndex());
        style.setFont(font);
        // 设置对齐方式
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        return style;
    }

    /**
     * 创建表头单元格样式
     */
    private static CellStyle createHeaderCellStyle(Workbook workbook) {
        CellStyle style = workbook.createCellStyle();
        style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        style.setBorderBottom(BorderStyle.THIN);
        style.setBorderTop(BorderStyle.THIN);
        style.setBorderRight(BorderStyle.THIN);
        style.setBorderLeft(BorderStyle.THIN);
        Font font = workbook.createFont();
        font.setBold(true);
        font.setFontHeightInPoints((short) 12);
        style.setFont(font);
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        return style;
    }

    /**
     * 创建数据单元格样式
     */
    private static CellStyle createDataCellStyle(Workbook workbook) {
        CellStyle style = workbook.createCellStyle();
        style.setBorderBottom(BorderStyle.THIN);
        style.setBorderTop(BorderStyle.THIN);
        style.setBorderRight(BorderStyle.THIN);
        style.setBorderLeft(BorderStyle.THIN);
        style.setAlignment(HorizontalAlignment.LEFT);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        style.setWrapText(true);
        return style;
    }

    /**
     * 创建标题行（合并首行所有列）
     */
    private static void createTitleRow(Sheet sheet, String title, int columnCount, CellStyle style) {
        // 创建标题行（第一行）
        Row titleRow = sheet.createRow(0);
        Cell titleCell = titleRow.createCell(0);
        titleCell.setCellValue(title);
        titleCell.setCellStyle(style);

        // 合并第一行的所有列
        sheet.addMergedRegion(new CellRangeAddress(
                0, 0, 0, columnCount - 1
        ));

        // 设置行高
        titleRow.setHeightInPoints(30);
    }

    /**
     * 创建表头行（第二行）
     */
    private static void createHeaderRow(Sheet sheet, String[] headers, CellStyle style) {
        Row headerRow = sheet.createRow(1); // 第二行
        for (int i = 0; i < headers.length; i++) {
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
            cell.setCellStyle(style);
        }
    }

    /**
     * 填充数据行（从第三行开始）
     */
    private static void fillDataRows(Sheet sheet, String[] headers,
                                     List<Map<String, Object>> data, CellStyle style) {
        for (int i = 0; i < data.size(); i++) {
            Row row = sheet.createRow(i + 2); // 从第三行开始
            Map<String, Object> rowData = data.get(i);

            for (int j = 0; j < headers.length; j++) {
                Cell cell = row.createCell(j);
                Object value = rowData.get(headers[j]);
                setCellValue(cell, value);
                cell.setCellStyle(style);
            }
        }
    }

    /**
     * 设置单元格值（支持多种数据类型）
     */
    private static void setCellValue(Cell cell, Object value) {
        if (value == null) {
            cell.setCellValue("");
        } else if (value instanceof String) {
            cell.setCellValue((String) value);
        } else if (value instanceof Number) {
            cell.setCellValue(((Number) value).doubleValue());
        } else if (value instanceof Boolean) {
            cell.setCellValue((Boolean) value);
        } else if (value instanceof java.util.Date) {
            cell.setCellValue((java.util.Date) value);
        } else {
            cell.setCellValue(value.toString());
        }
    }

    /**
     * 自动调整列宽
     */
    private static void autoSizeColumns(Sheet sheet, int columnCount) {
        for (int i = 0; i < columnCount; i++) {
            sheet.autoSizeColumn(i);
            // 设置最小宽度
            if (sheet.getColumnWidth(i) < 3000) {
                sheet.setColumnWidth(i, 3000);
            }
        }
    }

    /**
     * Spring Controller 使用示例
     */
    /*
    @GetMapping("/exportWithTitle")
    public void exportWithTitle(HttpServletResponse response) throws IOException {
        // 1. 准备数据
        String[] headers = {"ID", "姓名", "部门", "薪资"};
        List<Map<String, Object>> data = new ArrayList<>();

        Map<String, Object> row1 = new HashMap<>();
        row1.put("ID", 1001);
        row1.put("姓名", "张三");
        row1.put("部门", "技术部");
        row1.put("薪资", 15000);
        data.add(row1);

        // 2. 导出Excel（带标题）
        ExcelExportUtil.exportWithTitle(
            response,
            "员工信息报表",
            "员工数据",
            "2023年度员工信息汇总报表",
            headers,
            data
        );
    }
    */
}
